﻿
using MetroNextTools.NControls;
using MetroNextTools.NData;
using System;
using System.Collections.Specialized;
using Windows.Foundation;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
namespace MetroNextTools.NPanel
{
    public abstract class NCollectionPanel : Canvas
    {
        #region Fileds
        private bool _isGeneratorHooked;//判断Generator 是否注册ItemsChanged事件 
        #endregion

        #region Properties

        public INItemContainerGenerator ItemContainerGenerator
        {
            get
            {
                INItemContainerGenerator generator = this.GetGenerator();
                if (!_isGeneratorHooked)
                {
                    _isGeneratorHooked = true;
                    INNotifyItemsChanged notifyItemsChanged = generator as INNotifyItemsChanged;
                    if (notifyItemsChanged != null)
                    {
                        notifyItemsChanged.ItemsChanged += OnItemsChangedHandler;
                    }
                    generator.RemoveAll();
                }
                return generator;
            }
        }

        #endregion

        #region EventHandler

        void OnItemsChangedHandler(object sender, NEventArgs.NItemsChangedEventArgs e)
        {
            this.OnItemsChangedInternal(sender, e);
            base.InvalidateMeasure();
        }

        #endregion

        #region Method

        #region IItemContainerGenerator Handler

        public INItemContainerGenerator GetGenerator()
        {
            NItemsControl itemsOwner = NItemsControl.GetItemsOwner(this);
            if (itemsOwner == null)
            {
                throw new ArgumentNullException("The NItemsControl with the VirtualizingPanel is not found.");
            }
            return itemsOwner.ItemContainerGenerator;
        }


        private void OnItemsChangedInternal(object sender, NEventArgs.NItemsChangedEventArgs e)
        {
            NotifyCollectionChangedAction action = e.Action;
            if (action == NotifyCollectionChangedAction.Reset && base.Children.Count > 0)
            {
                this.ItemContainerGenerator.RemoveAll();
                base.Children.Clear();
                this.OnClearChildrenInternal();
            }
            this.OnItemsChanged(sender, e);
        }

        #endregion

        #region Internal add remove insert clear

        protected void AddInternalChild(UIElement child)
        {
            base.Children.Add(child);
        }

        protected void InsertInternalChild(int index, UIElement child)
        {
            base.Children.Insert(index, child);
        }

        protected void RemoveInternalChildRange(int index, int range)
        {
            int i = index + range;
            while (i > index)
            {
                base.Children.RemoveAt(--i);
            }
        }

        internal virtual void OnClearChildrenInternal()
        {
            this.OnClearChildren();
        }


        #endregion

        #region Virtual Method

        protected virtual void OnClearChildren()
        {

        }

        protected virtual void OnItemsChanged(object sender, NEventArgs.NItemsChangedEventArgs e)
        {

        }

        protected virtual void BringIndexIntoView(int index)
        {

        }

        #endregion

        #endregion

        /// <summary>
        /// 计算某个元素的位置
        /// </summary>
        /// <param name="ratioItem"></param>
        /// <returns></returns>
        public abstract Rect CaculatePosition(INRaitoItem ratioItem);

        /// <summary>
        /// 获取ItemsHostPanel当前最大长度
        /// </summary>
        /// <returns></returns>
        public abstract double GetMaxLength();
    }
}
